/*
enum Option<T> {
  Some(T),
  None
}
*/

fn main() {
  // let some_number = Option::Some(5);
  //↕ 等价
  let some_number = Some(5);
  println!("{:?}", some_number); //Some(5)
  let some_string = Some(String::from("a string"));

  let absent_number: Option<i32> = Option::None;
  //↕ 等价
  // let absent_number: Option<i32> = None;
  println!("{:?}", absent_number); //None


  // 用法, 场景
  let x: i32 = 5;
  let y: Option<i32> = Some(5);
  //↓ 运行会报错(编译不报)
  //let sum = x + y; //error[E0277]: cannot add `Option<i32>` to `i32`
  let mut temp = 0;
  match y {
    Some(i) => temp = i,
    _ => println!("do nothing")
  }
  let sum = x + temp;
  println!("{}", sum); //10
  //
  let result = plus_one(y);
  match result {
    Some(i) => println!("result = {}", i),
    None => println!("do nothing")
  }
  // ↑ 面的写法 可能在大多数情况下过于累赘 (通常我们只需满足一种模式)
  // So 可以使用 if let pattern
  // if let 语法让我们以一种不那么冗长的方式结合 if 和 let，来处理只匹配一个模式的值而忽略其他模式的情况
  if let Some(value) = plus_one(y/*y 必须要匹配 前面的 Some(value) 这个模式*/){
    println!("value = {}", value); //value = 6
  } else {
    println!("do nothing");
  }
}

fn plus_one(x: Option<i32>) -> Option<i32> {
  match x {
    None => None,
    Some(x) => Some(x + 1)
  }
}
